-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Rewrite legend visibility toggling #2022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/components/legend/draw.js
Outdated
case false: | ||
nextVisibility = false; | ||
break; | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔪 that default:
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅
src/components/legend/draw.js
Outdated
} | ||
|
||
// If not specified, assume visible: | ||
var curState = carr.get(fullTrace._group) || true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this ===
that || true
fallback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. This isn't a great conditional. If it's really fullData
, it should always be present and what it means to be. I think I'll just remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha couldn't remove it. Modified it to be a bit more targeted/explicit. The issue is that the container doesn't always have visible
defined. "Oh, so just use fullTrace.visible
." That didn't work either. Broke some tests. Aimed for some middle ground that passes all the tests.
src/components/legend/draw.js
Outdated
if(!carr) { | ||
var groupbyIndices = Registry.getTransformIndices(fullInput, 'groupby'); | ||
var lastGroupbyIndex = groupbyIndices[groupbyIndices.length - 1]; | ||
carr = Lib.keyedContainer(fullInput, 'transforms[' + lastGroupbyIndex + '].styles', 'target', 'value.visible'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keyedContainer
for the win 🏆
By the way, is carr
short for container array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... no need to rename carr
to something more explicit, I'm just curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's somewhat of a holdover. It's not great. Maybe kcont
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
carr
or kcont
, your call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kcont
. ✅
src/components/legend/draw.js
Outdated
} | ||
carrIdx[fullInput.index] = insertUpdate(fullInput.index, 'visible', fullInput.visible === false ? false : true); | ||
} else { | ||
// false -> false (not possible since will not be visible in legend) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌
src/components/legend/draw.js
Outdated
|
||
if(hasLegendgroup) { | ||
for(i = 0; i < fullData.length; i++) { | ||
if(fullData[i].visible && fullData[i].legendgroup === legendgroup) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe fullData[i].visible !== false
instead of fullData[i].visible
would be best, to make things more explicit. It is easy to forget that visible
supports two truthy values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅
src/components/legend/draw.js
Outdated
// Compute the clicked index. expandedIndex does what we want for expanded traces | ||
// but also culls hidden traces. That means we have some work to do. | ||
var clickedIndex, isIsolated, isClicked, isInGroup, otherState; | ||
for(clickedIndex = 0; clickedIndex < fullData.length; clickedIndex++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't clickedIndex
simply fullTrace.index
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's see… it might be. I need to think about this just a bit. fullTrace.index
vs. fullTrace._fullInput.index
vs. fullTrace._expandedIndex
obey slightly different rules. I think more often that not the answer was to avoid at all costs needing the index at all. I'll give the above a try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good catch. clickedIndex
isn't actually used at all, which was the end result of trying to get this right (i.e. don't use it at all). I've removed this code.
src/components/legend/draw.js
Outdated
@@ -520,52 +570,116 @@ function handleClick(g, gd, numClicks) { | |||
|
|||
Plotly.relayout(gd, 'hiddenlabels', hiddenSlices); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can return early after Plotly.relayout
for pie traces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore
src/components/legend/draw.js
Outdated
// The length of the value arrays should be equal and any unspecified | ||
// values should be explicitly undefined for them to get properly culled | ||
// as updates and not accidentally reset to the default value. This fills | ||
// out sparse arrays with the required number of undefined values: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice touch 👌
Very lovely PR ❤️ with strong tests ⚒️ I made a few comments; I'll make a second review after reading your answers. As an aside, |
Okay, I've made these changes. And since most of the other code was related to drawing, I've moved the click handler to a separate file. I left text editing in place since it's moderately short, though it could also be moved. |
src/components/legend/draw.js
Outdated
// ways to do this (e.g. why not just `curState = fullTrace.visible`??? The | ||
// answer is: because it breaks other things like groupby trace names in | ||
// subtle ways.) | ||
if(curState === undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comment 📚
💃 thanks very much @rreusser 🎉 |
Legend visibility toggling didn't work at all with
groupby
, which led to mostly a rewrite. By happenstance, it toggled them as a group, which wasn't really the desired behavior. More problematically though, it also threw lots ofUncaught bad container
errors because it really just wasn't accounted for at all. This PR rewrites legend visibility toggling and tries to preserve existing behavior while fixinggroupby
.In particular, one tricky case is
legendgroup
, both toggling and isolating:And the other is
groupby
transforms, both toggling and isolating: